<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Jessibuca Pro 3x3 demo</title>
    <script src="./jessibuca-pro.js"></script>
    <style>
        .root {
            display: flex;
            place-content: center;
            margin-top: 3rem;
        }

        .container-shell {
            backdrop-filter: blur(5px);
            background: hsla(0, 0%, 50%, 0.5);
            padding: 30px 4px 10px 4px;
            /* border: 2px solid black; */
            width: auto;
            position: relative;
            border-radius: 5px;
            box-shadow: 0 10px 20px;
        }

        .container-shell:before {
            content: "jessibuca Pro demo player";
            position: absolute;
            color: darkgray;
            top: 4px;
            left: 10px;
            text-shadow: 1px 1px black;
        }

        .container {
            background: rgba(13, 14, 27, 0.7);
            width: 320px;
            height: 199px;
            display: inline-block;
            margin-right: 10px;
            margin-bottom: 10px;
        }

        #container {

        }

        .input {
            display: flex;
            margin-top: 10px;
            color: white;
            place-content: stretch;
        }

        .input2 {
            bottom: 0px;
        }

        .input input {
            flex: auto;
        }

        .err {
            position: absolute;
            top: 40px;
            left: 10px;
            color: red;
        }

        .option {
            position: absolute;
            top: 4px;
            right: 10px;
            display: flex;
            place-content: center;
            font-size: 12px;
        }

        .option span {
            color: white;
        }

        .page {
            background: url('http://jessibuca.monibuca.com/bg.jpg');
            background-repeat: no-repeat;
            background-position: top;
        }

        @media (max-width: 720px) {
            .container {
                width: 90vw;
                height: 52.7vw;
            }
        }
    </style>
</head>
<body class="page">
<div class="root">

    <div class="container-shell">
        <div>
            <div class="container" id="container1"></div>
            <div class="container" id="container2"></div>
            <div class="container" id="container3"></div>
        </div>
        <div>
            <div class="container" id="container4"></div>
            <div class="container" id="container5"></div>
            <div class="container" id="container6"></div>
        </div>
        <div>
            <div class="container" id="container7"></div>
            <div class="container" id="container8"></div>
            <div class="container" id="container9"></div>
        </div>
        <div class="input">
            <div>
                当前浏览器：<span id="mseSupport" style="color: green;display: none">支持MSE H265解码</span>
                <span id="mseNotSupport" style="color: red;display: none">不支持MSE H265解码,会自动切换成wasm解码</span>
            </div>
        </div>
        <div class="input">
            <div>
                当前浏览器：<span id="wcsSupport" style="color: green;display: none">支持Webcodecs H265解码</span>
                <span id="wcsNotSupport" style="color: red;display: none">不支持Webcodecs H265解码(https/localhost),会自动切换成wasm解码</span>
            </div>
        </div>
        <div class="input">
            <div>
                当前浏览器：<span id="simdSupport" style="color: green;display: none">支持SIMD解码</span>
                <span id="simdNotSupport" style="color: red;display: none">不支持SIMD解码,会自动切换成wasm解码</span>
            </div>
        </div>
        <div class="input" style="width: 1000px;flex-direction: column">
            <div>
                js为单线程运行时, 无法通过多线程提升并发性能.
            </div>
            <div>将音视频解码在worker中进行, 能有效利用多核处理器提升多画面播放的流畅度.</div>
            <div>
                chrome限制同源http请求最多6个并发, 因此超过6个并发请求我们采用websocket-flv来播放
            </div>
            <div>请准备M7S服务端来测试. worker js不能跨域调用,</div>
        </div>
        <div class="input">
            <div><input
                type="checkbox"
                checked
                id="useMSE"
            /><span>MediaSource</span>
                <input
                    type="checkbox"
                    id="useWCS"
                /><span>Webcodec</span>
                <input
                    type="checkbox"
                    id="useSIMD"
                /><span>SIMD</span>
            </div>
        </div>
        <div class="input">
            <div>
                <span>缓存时长：</span>
                <input placeholder="单位：秒" type="text" id="videoBuffer" style="width: 50px" value="0.2">秒
                <span>缓存延迟(延迟超过会触发丢帧)：</span>
                <input placeholder="单位：秒" type="text" id="videoBufferDelay" style="width: 50px" value="2">秒
                <button id="replay">重播</button>
            </div>
        </div>
        <div class="input">
            <div>输入URL：</div>
            <input
                autocomplete="on"
                id="playUrl1"
                value=""
            />
        </div>
        <div class="input">
            <div>输入URL：</div>
            <input
                autocomplete="on"
                id="playUrl2"
                value=""
            />
        </div>
        <div class="input">
            <div>输入URL：</div>
            <input
                autocomplete="on"
                id="playUrl3"
                value=""
            />
        </div>
        <div class="input">
            <div>输入URL：</div>
            <input
                autocomplete="on"
                id="playUrl4"
                value=""
            />
        </div>
        <div class="input">
            <div>输入URL：</div>
            <input
                autocomplete="on"
                id="playUrl5"
                value=""
            />
        </div>
        <div class="input">
            <div>输入URL：</div>
            <input
                autocomplete="on"
                id="playUrl6"
                value=""
            />
        </div>
        <div class="input">
            <div>输入URL：</div>
            <input
                autocomplete="on"
                id="playUrl7"
                value=""
            />
        </div>
        <div class="input">
            <div>输入URL：</div>
            <input
                autocomplete="on"
                id="playUrl8"
                value=""
            />
        </div>
        <div class="input">
            <div>输入URL：</div>
            <input
                autocomplete="on"
                id="playUrl9"
                value=""
            />
        </div>
        <div class="input">
            <button id="play">播放</button>
            <button id="pause" style="display: none">停止</button>
        </div>
        <div class="input" style="line-height: 30px">
            <button id="destroy">销毁</button>
        </div>
    </div>
</div>


<script>
    var $player = document.getElementById('play');
    var $pause = document.getElementById('pause');
    var $destroy = document.getElementById('destroy');
    var $useMSE = document.getElementById('useMSE');
    var $useSIMD = document.getElementById('useSIMD');
    var $useWCS = document.getElementById('useWCS');
    var $videoBuffer = document.getElementById('videoBuffer');
    var $videoBufferDelay = document.getElementById('videoBufferDelay');
    var $replay = document.getElementById('replay');

    var showOperateBtns = true; // 是否显示按钮
    var forceNoOffscreen = true; //
    var playList = [];
    let size = 9

    function _create(id) {
        var $container = document.getElementById('container' + id);

        var jessibuca = new JessibucaPro({
            container: $container,
            decoder: './decoder-pro.js',
            videoBuffer: 0.2, // 缓存时长
            isResize: false,
            text: "",
            loadingText: "加载中",
            debug: true,
            isMulti: true,
            useMSE: $useMSE.checked === true,
            useSIMD: $useSIMD.checked === true,
            useWCS: $useWCS.checked === true,
            hasAudio: false,
            useVideoRender: true,
            controlAutoHide: true,
            showBandwidth: showOperateBtns, // 显示网速
            showPerformance: showOperateBtns,
            operateBtns: {
                fullscreen: showOperateBtns,
                screenshot: showOperateBtns,
                play: showOperateBtns,
                audio: showOperateBtns,
            },
            watermarkConfig: {
                text: {
                    content: 'jessibuca-pro'
                },
                right: 10,
                top: 10
            },
        },);

        // jessibuca.onLog = msg => console.error(msg);
        // jessibuca.onRecord = (status) => console.log('onRecord', status);
        // jessibuca.onPause = () => console.log('onPause');
        // jessibuca.onPlay = () => console.log('onPlay');
        // jessibuca.onMute = msg => console.log('onMute', msg);
        jessibuca.on("fullscreen", function (flag) {
            console.log('is fullscreen', id, flag)
        })
        playList.push(jessibuca);
    }

    function create() {
        for (let i = 0; i < size; i++) {
            _create(i + 1);
            $player.style.display = 'inline-block';
            $pause.style.display = 'none';
            $destroy.style.display = 'none';
        }
    }
    create();
    function play() {
        for (let i = 0; i < size; i++) {
            var id = i + 1;
            var $playHref = document.getElementById('playUrl' + id);
            let player = playList[i];
            if ($playHref.value) {
                setTimeout((url) => {
                    console.log(url);
                    player && player.play(url).then(() => {

                    }).catch((e) => {
                        console.error(e);
                    });
                }, 0, $playHref.value)
            }
        }

        $player.style.display = 'none';
        $pause.style.display = 'inline-block';
        $destroy.style.display = 'inline-block';
    }
    function destroy() {
        return new Promise((resolve, reject) => {
            const destroyList = [];
            for (let i = 0; i < size; i++) {
                let player = playList[i];
                if (player) {
                    destroyList.push(player.destroy());
                }
            }
            Promise.all(destroyList).then(() => {
                playList = [];
                setTimeout(() => {
                    for (let i = 0; i < size; i++) {
                        create(i + 1);
                    }
                    $player.style.display = 'inline-block';
                    $pause.style.display = 'none';
                    $destroy.style.display = 'none';
                    resolve();
                }, 100)
            }).catch((e) => {
                console.error(e);
            })
        })

    }

    function replay() {
        destroy().then(() => {
            create();
            play();
        });
    }


    function pause() {
        $player.style.display = 'inline-block';
        $pause.style.display = 'none';
        for (let i = 0; i < size; i++) {
            let player = playList[i];
            player && player.pause()
        }
    }

    $player.addEventListener('click', function () {
        play();
    }, false)


    $pause.addEventListener('click', function () {
        pause();
    })

    $destroy.addEventListener('click', function () {
        destroy().then(() => {

        });
    })

    $replay.addEventListener('click', function () {
        replay();
    })

    $useMSE.addEventListener('click', function () {
        const checked = $useMSE.checked;
        if (checked) {
            $useSIMD.checked = false
            $useWCS.checked = false
        }
        replay();
    })

    $useSIMD.addEventListener('click', function () {
        const checked = $useSIMD.checked;
        if (checked) {
            $useMSE.checked = false
            $useWCS.checked = false
        }
        replay();
    })

    $useWCS.addEventListener('click', function () {
        const checked = $useWCS.checked;
        if (checked) {
            $useMSE.checked = false
            $useSIMD.checked = false
        }
        replay();
    })

    function getBrowser() {
        const UserAgent = window.navigator.userAgent.toLowerCase() || '';
        const browserInfo = {};
        const browserArray = {
            IE: window.ActiveXObject || "ActiveXObject" in window, // IE
            Chrome: UserAgent.indexOf('chrome') > -1 && UserAgent.indexOf('safari') > -1, // Chrome浏览器
            Firefox: UserAgent.indexOf('firefox') > -1, // 火狐浏览器
            Opera: UserAgent.indexOf('opera') > -1, // Opera浏览器
            Safari: UserAgent.indexOf('safari') > -1 && UserAgent.indexOf('chrome') == -1, // safari浏览器
            Edge: UserAgent.indexOf('edge') > -1, // Edge浏览器
            QQBrowser: /qqbrowser/.test(UserAgent), // qq浏览器
            WeixinBrowser: /MicroMessenger/i.test(UserAgent) // 微信浏览器
        };
        // console.log(browserArray)
        for (let i in browserArray) {
            if (browserArray[i]) {
                let versions = '';
                if (i === 'IE') {
                    const versionArray = UserAgent.match(/(msie\s|trident.*rv:)([\w.]+)/)
                    if (versionArray && versionArray.length > 2) {
                        versions = UserAgent.match(/(msie\s|trident.*rv:)([\w.]+)/)[2];
                    }
                } else if (i === 'Chrome') {
                    for (let mt in navigator.mimeTypes) {
                        //检测是否是360浏览器(测试只有pc端的360才起作用)
                        if (navigator.mimeTypes[mt]['type'] === 'application/360softmgrplugin') {
                            i = '360';
                        }
                    }
                    const versionArray = UserAgent.match(/chrome\/([\d.]+)/);
                    if (versionArray && versionArray.length > 1) {
                        versions = versionArray[1];
                    }
                } else if (i === 'Firefox') {
                    const versionArray = UserAgent.match(/firefox\/([\d.]+)/);
                    if (versionArray && versionArray.length > 1) {
                        versions = versionArray[1];
                    }
                } else if (i === 'Opera') {
                    const versionArray = UserAgent.match(/opera\/([\d.]+)/);
                    if (versionArray && versionArray.length > 1) {
                        versions = versionArray[1];
                    }
                } else if (i === 'Safari') {
                    const versionArray = UserAgent.match(/version\/([\d.]+)/);
                    if (versionArray && versionArray.length > 1) {
                        versions = versionArray[1];
                    }
                } else if (i === 'Edge') {
                    const versionArray = UserAgent.match(/edge\/([\d.]+)/);
                    if (versionArray && versionArray.length > 1) {
                        versions = versionArray[1];
                    }
                } else if (i === 'QQBrowser') {
                    const versionArray = UserAgent.match(/qqbrowser\/([\d.]+)/);
                    if (versionArray && versionArray.length > 1) {
                        versions = versionArray[1];
                    }
                }
                browserInfo.type = i;
                browserInfo.version = parseInt(versions);
            }
        }
        return browserInfo;
    }


    function checkSupportMSEHevc() {
        return window.MediaSource && window.MediaSource.isTypeSupported('video/mp4; codecs="hev1.1.6.L123.b0"');
    }

    function checkSupportWCSHevc() {
        const browserInfo = getBrowser();

        return browserInfo.type.toLowerCase() === 'chrome' && browserInfo.version >= 107 && (location.protocol === 'https:' || location.hostname === 'localhost');
    }

    function checkSupportSIMD() {
        return WebAssembly && WebAssembly.validate(new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 5, 1, 96, 0, 1, 123, 3, 2, 1, 0, 10, 10, 1, 8, 0, 65, 0, 253, 15, 253, 98, 11]));
    }

    let support = document.getElementById('mseSupport');
    let notSupport = document.getElementById('mseNotSupport');
    if (checkSupportMSEHevc()) {
        support.style.display = 'inline-block'
    } else {
        notSupport.style.display = 'inline-block'
    }

    let supportWcsHevc = document.getElementById('wcsSupport');
    let notSupportWcsHevc = document.getElementById('wcsNotSupport');

    if (checkSupportWCSHevc()) {
        supportWcsHevc.style.display = 'inline-block';
    } else {
        notSupportWcsHevc.style.display = 'inline-block'
    }


    let supportSimd = document.getElementById('simdSupport');
    let notSupportSimd = document.getElementById('simdNotSupport');

    if (checkSupportSIMD()) {
        supportSimd.style.display = 'inline-block';
    } else {
        notSupportSimd.style.display = 'inline-block'
    }


</script>

</body>
</html>
